<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* CI TaMeR Helpers
*
* @package		CodeIgniter
* @subpackage	Helpers
* @category    Helpers
* @author		Dennis T. Kaplan
* @CI alias    TaMeR
*/

    /**
     * @note	WhoIs
     * @info	Who Is Online
     * @author	Dennis T. Kaplan
     * @access	public
     * @param	 
     * @return	String
     */	
    function WhoIs()
    {
        $time = time() - (5 * 60); // 5 Minutes
    	$sql = 'SELECT `session_last_activity`, `session_data` FROM `session` WHERE `session_last_activity` > '.$time.' ORDER BY `session_last_activity` DESC';
        $result = mysql_query($sql);
        if (!$result) {
            die('Invalid query: ' . mysql_error());
        }
        while ($row = mysql_fetch_assoc($result)) {
            $data[] = unserialize($row['session_data']);
        }
        mysql_free_result($result);
        
        $return = 'Who Is Online<ul>';
        foreach($data as $v){
            if(isset($v['Alias'])){
                $return .= '<li>'.$v['Alias'].'</li>';
            }
        }
        $return .= '</ul>';
        
        return $return;
    }






/**
 * Formats a number by injecting nonnumeric characters in a specified format
 * into the string in the positions they appear in the format.
 *
 * <strong>Example:</strong>
 * <code>
 *  echo format_string('1234567890', '(000) 000-0000');
 *  // => (123) 456-7890
 *
 *  echo format_string('1234567890', '000.000.0000');
 *  // => 123.456.7890
 * </code>
 *
 * @param string the string to format
 * @param string the format to apply
 * @return the formatted string
 */
function format_string($string, $format)
{
   if ($format == '' || $string == '') return $string;
 
   $result = '';
   $fpos = 0;
   $spos = 0;
   while ((strlen($format) - 1) >= $fpos)
   {
       if (is_alphanumeric(substr($format, $fpos, 1)))
       {
           $result .= substr($string, $spos, 1);
           $spos++;
       }
       else
       {
           $result .= substr($format, $fpos, 1);
       }
 
       $fpos++;
   }
 
   return $result;
}
 


/**
 * @note	select_options
 * @info	Create select oprions from array 
 *
 * @access	public
 * @param	$ao, may be an object or $array
 * @param   $sel = string
 * @return	string  is_object($)
 */	
 function select_options($ao, $sel = '')  
 {
     if(is_object($ao)) $ao = (array) $ao;
     $r = '';
     if(!isset($sel) || $sel === FALSE){
         $sel = '';
     }elseif ($sel === TRUE){
             $r .= "\t<option> </option>\n";
             $sel = '';
     }else{
         $sel = 'selected="selected" ';
     }
     foreach($ao as $k=>$v) {
         $r .= "\t".'<option '.$sel.'value="'.$k.'">'.$v."</option>\n";
     }
     return $r;
}


/** dbMeta to formMeta ---**************************************************
/************************** START UNSET/DEL IDS ****************************
*  Removes id, *_id and also first and last date fields from database array
****************************************************************************/

function delids(&$array)
{
    $array = (array) $array;
	if(isset($array[0])){
		foreach($array as $k => $v){
			$array[$k] = unsetids($v);
		}
	}else{
		unsetids($array);
	}
}

function unsetids(&$array)
{
    $keys = array_keys($array);
    foreach($keys as $v){
		if($v=='id')unset($array[$v]);
        if($v=='uid')unset($array[$v]);
		if($v=='last')unset($array[$v]);
		if($v=='first')unset($array[$v]);
        if($v=='added')unset($array[$v]);
        if($v=='updated')unset($array[$v]);
        if($v=='user_id')unset($array[$v]);
    }
    $keys = array_keys($array);
    foreach($keys as $v){
		if(strstr($v, '_id')){
            $r = trim($v, '_id');
            $array[$r] = $array[$v];
            unset($array[$v]);
        }
    }
}



/** Post to dbMeta **************************************************
*
* Renames post values from formMeta key back to dbMeta key
*
* We remove the '_id' keys in dbMeta before we save them as formMeta
* here we retore those again so we can save the data in the db.
* @access	public
* @param	array $post, array $dbMeta
* @return	array
*/ 
function resetids(&$post,$dbMeta)
{
    $post_keys = array_keys($post);
    $meta_keys = array_keys($dbMeta);
    foreach($post_keys as $pk){
        foreach($meta_keys as $mk){
            if(strstr($mk, '_id')){
                $mkt = trim($mk, '_id');
                if($mkt == $pk){
                    $post_keys[$mkt] = $post_keys[$pk];
                    unset($post_keys[$pk]);                    
                }
            }
        }
    }
    return $post_keys;
}

// Here compare the values from the post to the db to find any changed values.
function new_value($alldbvars,$newvars) {
	$return = array();
    foreach($alldbvars as $k => $v){
        if($newvars[$k] != $v) $return[$k] = $newvars[$k];
    }
    return $return;
}

// ------------------------------------------------------------------------

/**
* reverse strstr()
*
* Returns part of haystack string from start to the first occurrence of needle
* $haystack = 'this/that/theother';
* $result = rstrstr($haystack, '/')
* $result == this

* @access	public
* @param		string $haystack, string $needle
* @return	string
*/    
function rstrstr($haystack,$needle)
{
	return substr($haystack, 0,strpos($haystack, $needle));
}


function getip() {
    if (getenv('HTTP_CLIENT_IP')) {
        $IP = getenv('HTTP_CLIENT_IP');
    }
    elseif (getenv('HTTP_X_FORWARDED_FOR')) {
        $IP = getenv('HTTP_X_FORWARDED_FOR');
    }
    elseif (getenv('HTTP_X_FORWARDED')) {
        $IP = getenv('HTTP_X_FORWARDED');
    }
    elseif (getenv('HTTP_FORWARDED_FOR')) {
        $IP = getenv('HTTP_FORWARDED_FOR');
    }
    elseif (getenv('HTTP_FORWARDED')) {
        $IP = getenv('HTTP_FORWARDED');
    }
    else {
        $IP = $_SERVER['REMOTE_ADDR'];
    }
    
    if (strstr($IP, ', ')) {
        $ips = explode(', ', $IP);
        $IP = $ips[0];
    }
    return($IP);
}

// ------------------------------------------------------------------------

/**
* printa
*
* Print Array 
*
* @access	public
* @param	array
* @return	array name and output of array in pre as print_r
*/	

function printa(&$a){
    $caller_info = array_shift(debug_backtrace());
    $lines = file($caller_info['file']);
    $line = $lines[$caller_info['line'] - 1];
    if(preg_match('/printa\\s*\\(\$(\\w+)/', $line, $matches)) {
            $name_of_my_array = $matches[1];
    }
    echo "<hr><h3>". $name_of_my_array . "<pre>";
    print_r($a);
    echo "</pre></h3><hr>";
}



//abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
function randString($l=6,$c='abcdefghjkmnopqrstuvwxyz0123456789')
{
    $string = '';
    for($i = 1; $i <= $l; $i++)
        $string .= $c[rand(0,strlen($c)-1)];
    return $string;
}

// $uid = $this->fun->dbid();
function dbid()
{
    //$sql = "SELECT id FROM `unique` WHERE `id` = $no OR `user_id` = $no LIMIT 1 ";
    $no = mt_rand(1000000001,9999999998);
    return $no;
}



/*************************************************
* Zwo function clean phone and format phone
***/

function format_phone($phone)
{
    $phone = clean_phone($phone);
    $ret = '';
    $ext = '';
    $i = strpos($phone,'x');
    if ($i !== FALSE)
    {
        // Contains extension
        $ext    = ' '.substr($phone,$i);
        $phone  = substr($phone,0,$i);
    }
    // Phones with no extension
    switch(strlen($phone))
    {
    case 7:
        $ret = substr($phone, 0, 3)."-".substr($phone, 3);
        break;
    case 8:
        $ret = substr($phone, 0, 4)."-".substr($phone, 4);
        break;
    case 10:
        $ret = "(".substr($phone, 0, 3).") ".substr($phone, 3, 3)."-".substr($phone, 6, 4);
        break;
    default:
        $ret = $phone;
    }
    return $ret.$ext;
}

function clean_phone($phone)
{
    $r = '';
    $p = strtolower($phone);
    for ($i=0;$i<strlen($p);$i++)
    {
        $a = ord(substr($p, $i, 1));
        // If ( Not Numeric ) or ( Not 'x' )
        if ((($a >= 48) && ($a <= 57)) || ($a == 120)) $r .= substr($p, $i, 1);
    }
    return $r;
}

#####
# URL  Validator
#####   


/**
* @copyright 2004   Esben Maaløe esm-at-baseclassmodulweb.dk
* @author   Esben Maaløe esm-at-baseclassmodulweb.dk
* @license You are free to copy/modify this function to your hearts content
*          However I ask that you return any improvements you make to me,
*          and that you credit me in your sourcecode if you use it
* @version 0.24
* @url      http://baseclass.modulweb.dk/urlvalidator/index.php
*/

/*
A typical internet mailcheck:
$options = array(
    'Require' => array(
        'User' => true,
        'Server' => true,
        'TLD' => true,
        ),
    
    'Forbid' => array(
        'Protocol' => true,
        'Resource' => true,
        'Port' => true,
        'QueryString' => true,
        'Anchor' => true,
        ),
    'AllowedProtocols' => array('mailto'),
    'AssumeProtocol' => 'mailto',
    );

$result = _ValURL($emailaddress, $options);

A typical HTTP internet URL check:
$options = array(
    'Require' => array(
        'TLD' => true,
        'Server' => true,
        ),
    'AllowedProtocols' => array('http', 'https'),
    'AllowBracks' => true,
    'AssumeProtocol' => 'http',
    ); 

Last validation used:
$options =    array   
( 
    'AssumeProtocol' =>   'http'   ,   
    'AllowBracks' =>  TRUE  ,   
    'AllowedProtocols' =>   array   
    ( 
        0 =>   'http'   ,   
        1 =>   'https'   ,   
        ) ,  
    'Require' =>   array   
    ( 
        'Protocol' =>  FALSE  ,   
        'User' =>  FALSE  ,   
        'Password' =>  FALSE  ,   
        'Server' =>  TRUE  ,   
        'Resource' =>  FALSE  ,   
        'TLD' =>  TRUE  ,   
        'Port' =>  FALSE  ,   
        'QueryString' =>  FALSE  ,   
        'Anchor' =>  FALSE  ,   
        ) ,  
    'Forbid' =>   array   
    ( 
        'Protocol' =>  FALSE  ,   
        'User' =>  FALSE  ,   
        'Password' =>  FALSE  ,   
        'Server' =>  FALSE  ,   
        'Resource' =>  FALSE  ,   
        'TLD' =>  FALSE  ,   
        'Port' =>  FALSE  ,   
        'QueryString' =>  FALSE  ,   
        'Anchor' =>  FALSE  ,   
        ) ,  
    )  


*/ 

function ValURL($value, $options = array())
{
    $value = trim($value);
    
    if (!$value)
        return array('Result' => array(EW_ERR_URL_EMPTY_STRING), 'Value' => '');
    
    /* Set up default options */
    $options = array_merge(array(/**/
        'AllowedProtocols' => array(), /* array('http', 'https', etc...) always lcase! */
        'AllowBracks' => false, /* Allow square brackets in the query string ? */
        'Protocols' => array('http', 'https', 'ftp', 'mailto', 'file', 'news', 'gopher', 'telnet', 'nntp'), /**/
        'AssumeProtocol' => false, /**/
        ), $options);
    
    /* Setup default values for $options['Require]*/
    @ $options['Require'] = array_merge(array(/**/
        'Protocol' => false, /**/
        'User' => false, /**/
        'Password' => false, /**/
        'Server' => false, /**/
        'TLD' => false, /**/
        'Port' => false, /**/
        'Resource' => false, /**/
        'QueryString' => false, /**/
        'Anchor' => false, /**/
        ), $options['Require']);
    
    /* Setup default values for $options['Forbid]*/
    @ $options['Forbid'] = array_merge(array(/**/
        'Protocol' => false, /**/
        'User' => false, /**/
        'Password' => false, /**/
        'Server' => false, /**/
        'TLD' => false, /**/
        'Port' => false, /**/
        'Resource' => false, /**/
        'QueryString' => false, /**/
        'Anchor' => false, /**/
        ), $options['Forbid']);
    
    /* Create a container for the URL parts*/
    $url = array(/**/
        'Protocol' => '', /**/
        'User' => '', /**/
        'Password' => '', /**/
        'Server' => '', /**/
        'Port' => '', /**/
        'Resource' => '', /**/
        'TLD' => '', /**/
        'QueryString' => '', /**/
        'Anchor' => '');
    
    /* Setup errorcodes for invalid elements */
    $errCodeInvalid = array(/**/
        'Protocol' => EW_ERR_URL_INVALID_PROTOCOL, /**/
        'User' => EW_ERR_URL_INVALID_USER, /**/
        'Password' => EW_ERR_URL_INVALID_PASSWORD, /**/
        'Server' => EW_ERR_URL_INVALID_SERVER, /**/
        'TLD' => EW_ERR_URL_INVALID_TLD, /**/
        'Port' => EW_ERR_URL_INVALID_PORT, /**/
        'Resource' => EW_ERR_URL_INVALID_RESOURCE, /**/
        'QueryString' => EW_ERR_URL_INVALID_QUERYSTRING, /**/
        'Anchor' => EW_ERR_URL_INVALID_ANCHOR);
    
    /* Setup errorcodes for missing elements */
    $errCodeMissing = array(/**/
        'Protocol' => EW_ERR_URL_MISSING_PROTOCOL, /**/
        'User' => EW_ERR_URL_MISSING_USER, /**/
        'Password' => EW_ERR_URL_MISSING_PASSWORD, /**/
        'Server' => EW_ERR_URL_MISSING_SERVER, /**/
        'TLD' => EW_ERR_URL_MISSING_TLD, /**/
        'Port' => EW_ERR_URL_MISSING_PORT, /**/
        'Resource' => EW_ERR_URL_MISSING_RESOURCE, /**/
        'QueryString' => EW_ERR_URL_MISSING_QUERYSTRING, /**/
        'Anchor' => EW_ERR_URL_MISSING_ANCHOR);
    
    /* set up some needed vars */
    extract($options);
    $errArr = array();
    $tmpValue = $value;
    $lcValue = strtolower($value);
    
    /**
    * Split the url into it's subparts
    */
    
    foreach ($Protocols as $key => $protocol)
    {
        if (strpos($lcValue, "$protocol:") === 0)
        {
            $tmp = explode(':', $tmpValue, 2);
            $url['Protocol'] = $tmp[0];
            $tmpValue = $tmp[1];
            
            if ($url['Protocol'] == 'mailto' || $url['Protocol'] == 'news')
            {
                
                /* Check for % that is NOT an escape sequence */
                if (preg_match('/%[^a-f0-9]/i', $tmpValue) || preg_match("/^[^a-z0-9;&=+$,_.!*'()%~-]/i", $tmpValue))
                {
                    $errArr[EW_ERR_URL_INVALID_PROTOCOL] = EW_ERR_URL_INVALID_PROTOCOL;
                }
            }
            else
            {
                if (!(strpos($tmpValue, '//') === 0))
                {
                    $errArr[EW_ERR_URL_INVALID_PROTOCOL] = EW_ERR_URL_INVALID_PROTOCOL;
                }
                else
                {
                    $tmpValue = substr($tmpValue, 2);
                }
            }
        }
    }
    
    if (!$url['Protocol'])
    {
        if (strpos(strtolower($tmpValue), ('mailto:')) === 0 || strpos(strtolower($tmpValue), ('news:')) === 0)
            $tmp = ':';
        else
        $tmp = '://';
        
        $tmp = explode($tmp, $tmpValue, 2);
        if (count($tmp) == 2)
        {
            $url['Protocol'] = strtolower($tmp[0]);
            $tmpValue = $tmp[1];
        }
    }
    
    $tmp = explode('?', $tmpValue);
    
    if (count($tmp) > 1)
    {
        $tmpValue = $tmp[0];
        $url['QueryString'] = $tmp[1];
        
        $tmp = explode('#', $url['QueryString']);
        if (count($tmp) > 1)
        {
            $url['QueryString'] = $tmp[0];
            $url['Anchor'] = $tmp[1];
        }
    }
    else
    {
        $tmp = explode('#', $tmpValue);
        if (count($tmp) > 1)
        {
            $tmpValue = $tmp[0];
            $url['Anchor'] = $tmp[1];
        }
    }
    
    $tmp = explode('/', $tmpValue, 2);
    if (count($tmp) > 1)
    {
        $url['Server'] = strtolower($tmp[0]);
        $url['Resource'] = $tmp[1];
    }
    else
    {
        $url['Server'] = strtolower($tmpValue);
    }
    
    /* User / password */
    $tmp = explode('@', $url['Server']);
    if (count($tmp) > 1)
    {
        $url['User'] = $tmp[0];
        $url['Server'] = $tmp[1];
        
        if ($url['User'])
        {
            $tmp = explode(':', $url['User']);
            if (count($tmp) > 1)
            {
                $url['User'] = $tmp[0];
                $url['Password'] = $tmp[1];
            }
        }
    }
    
    $tmp = explode(':', $url['Server'], 2);
    if (count($tmp) > 1)
    {
        if ($tmp[0])
        {
            $url['Server'] = $tmp[0];
            $url['Port'] = $tmp[1];
            
        }
    }
    
    if (!$url['Protocol'] && !$url['Password'] && in_array(strtolower($url['User']), array('mail', 'news')))
    {
        $url['Protocol'] = strtolower($url['User']);
        $url['User'] = '';
        
    }
    
    if ($url['Protocol'] == 'mailto' && $url['Server'] && !$url['User'])
    {
        $url['User'] = $url['Server'];
        $url['Server'] = '';
    }
    
    /**
    * Validate the different subparts
    */
    
    /* Check the protocol */
    if ($url['Protocol'])
    {
        $tmp = preg_replace("/[^a-z0-9+-.]/", '', $url['Protocol']);
        
        if ($tmp != $url['Protocol'])
        {
            $errArr[EW_ERR_URL_INVALID_PROTOCOL] = EW_ERR_URL_INVALID_PROTOCOL;
        }
        
        if (count($options['AllowedProtocols']))
            if (!in_array($url['Protocol'], $options['AllowedProtocols']))
            $errArr[EW_ERR_URL_INVALID_PROTOCOL] = EW_ERR_URL_INVALID_PROTOCOL;
        
    }
    
    /* check userinfo */
    if ($url['User'])
    {
        /* Check for % that is NOT an escape sequence */
        if (preg_match('/%[^a-f0-9]/i', $url['User']) || preg_match("/[^a-z0-9;&=+$,_.!~*'()%-]/i", $url['User']))
        {
            $errArr[EW_ERR_URL_INVALID_USER] = EW_ERR_URL_INVALID_USER;
            $url['User'] = urlencode(urldecode($url['User']));
        }
    }
    if ($url['Password'])
    {
        /* Check for % that is NOT an escape sequence */
        if (preg_match('/%[^a-f0-9]/i', $url['Password']) || preg_match("/[^a-z0-9;&=+$,_.!~*'()%-]/i", $url['Password']))
        {
            $errArr[EW_ERR_URL_INVALID_PASSWORD] = EW_ERR_URL_INVALID_PASSWORD;
        }
        $url['Password'] = urlencode(urldecode($url['Password']));
    }
    
    //      userinfo      = *( unreserved | escaped |
        //                         ";" | ":" | "&" | "=" | "+" | "$" | "," )
    //      unreserved    = alphanum | mark
    //      mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
    //                      "(" | ")"
    
    //      escaped       = "%" hex hex
    /* Check if the server part is an ip */
    if ($url['Server'])
    {
        if (!preg_match('/[^.0-9]/', $url['Server']))
        {
            $ServerIsIP = true;
            
            $ipErr = false;
            
            $ipPart = explode('.', $url['Server']);
            
            if ($ipPart[0] > 224 || $ipPart[0] == 0)
            {
                $errArr[EW_ERR_URL_INVALID_SERVER] = EW_ERR_URL_INVALID_SERVER;
            }
            else
            {
                for ($i = 1; $i < 4; $i ++)
                {
                    $ipPart[$i] = (integer) $ipPart[$i];
                    if ($ipPart[$i] > 255)
                        $errArr[EW_ERR_URL_INVALID_SERVER] = EW_ERR_URL_INVALID_SERVER;
                }
            }
            
            /**
            * @todo Implement checking for reserved class D and E, and
            * other reserved addresses such as 0.0.0.0 or 255.255.255.255
            * and ip-addresses where either the host or the network part
            * is all binary 0s or all binary 1s
            * check:
            * http://www.cisco.com/univercd/cc/td/doc/product/atm/l2020/2020r21x/planning/appndxa.htm#xtocid87496
            */
            
            $url['Server'] = join('.', $ipPart);
        }
        /* url is not an ip */
        else
        {
            $ServerIsIP = false;
            
            $serverParts = explode('.', $url['Server']);
            
            /* check serverparts */
            for ($i = 0; $i < count($serverParts); $i ++)
            {
                $tmp = preg_replace('/[^a-z0-9-]/', '', $serverParts[$i]);
                
                /* Check if it is a top-level server */
                if ($i  && $i == count($serverParts) - 1)
                    $tmp = preg_replace('/^[^a-z]/', '', $tmp);
                else
                $tmp = preg_replace('/^[^a-z0-9]/', '', $serverParts[$i]);
                
                $tmp = preg_replace('/[^a-z0-9]$/', '', $tmp);
                
                if ($tmp != $serverParts[$i])
                {
                    if ($tmp != '')
                        $serverParts[$i] = $tmp;
                    else
                    unset($serverParts[$i]);
                    
                    $errArr[EW_ERR_URL_INVALID_SERVER] = EW_ERR_URL_INVALID_SERVER;
                    
                }
            }
            
            if (count($serverParts) < 2)
            {
                if ($Require['TLD'])
                {
                    $errArr[EW_ERR_URL_MISSING_TLD] = EW_ERR_URL_MISSING_TLD;
                }
            }
            else
            {
                
                $url['TLD'] = $serverParts[count($serverParts) - 1];
            }
            
            $url['Server'] = join('.', $serverParts);
        }
    }
    
    /* Check the Port */
    if ($url['Port'])
    {
        $tmp = (integer) $url['Port'];
        if ($url['Port'] != (string) $tmp)
        {
            $errArr[EW_ERR_URL_INVALID_PORT] = EW_ERR_URL_INVALID_PORT;
            
            $url['Port'] = '';
        }
        else
        {
            $url['Port'] = $tmp;
            if ($url['Port'] > 65535)
                $errArr[EW_ERR_URL_INVALID_PORT] = EW_ERR_URL_INVALID_PORT;
        }
        
    }
    
    /* Check the resource */
    //path          = [ abs_path | opaque_part ]
    //path_segments = segment *( "/" segment )
    //segment       = *pchar *( ";" param )
    //param         = *pchar
    //pchar         = unreserved | escaped |
    //                ":" | "@" | "&" | "=" | "+" | "$" | ","
    
    if ($url['Resource'])
    {
        $resourceParts = explode('/', $url['Resource']);
        
        if ($resourceParts[count($resourceParts) - 1] == '')
            array_pop($resourceParts);
        
        if ($resourceParts[0] == '')
            unset($resourceParts[0]);
        
        foreach ($resourceParts as $key => $part)
        {
            if ($part == '')
            {
                $errArr[EW_ERR_URL_INVALID_RESOURCE] = EW_ERR_URL_INVALID_RESOURCE;
                unset($resourceParts[$key]);
            }
            
            /* Check for % that is NOT an escape sequence || invalid chars*/
            elseif (preg_match('/%[^a-f0-9]/i', $part) || preg_match("/[^@a-z0-9_.!~*'()$+&,%:=;?-]/i", $part))
            {
                $errArr[EW_ERR_URL_INVALID_RESOURCE] = EW_ERR_URL_INVALID_RESOURCE;
                $resourceParts[$key] = urlencode(urldecode($part));
            }
            
            /* check for invalid chars */
            
        }
        $url['Resource'] = join('/', $resourceParts);
    }
    
    if ($url['QueryString'])
    {
        
        /* Check for % NOT part of an escape sequence || invalid chars */
        $tmp = $options['AllowBracks'] ? /**/
        "^a-z0-9_.!~*'()%;\/?:@&=+$,\[\]-" : /**/
        "^a-z0-9_.!~*'()%;\/?:@&=+$,-"; /**/
        
        if (preg_match('/%[^a-f0-9]/i', $url['QueryString']) || preg_match("/[$tmp]+/i", $url['QueryString']))
        {
            $errArr[EW_ERR_URL_INVALID_QUERYSTRING] = EW_ERR_URL_INVALID_QUERYSTRING;
            $url['QueryString'] = $url['QueryString'];
        }
        
    }
    if ($url['Anchor'])
    {
        if (preg_match('/%[^a-f0-9][a-f0-9]?/i', $url['Anchor']) || //
            preg_match("/[^a-z0-9-_.!~*'()%;\/?:@&=+$,]/i", $url['Anchor']))
        {
            $errArr[EW_ERR_URL_INVALID_ANCHOR] = EW_ERR_URL_INVALID_ANCHOR;
            $url['Anchor'] = $url['Anchor'];
        }
        
    }
    foreach ($url as $partName => $notused)
    {
        if ($partName == 'TLD' && $ServerIsIP)
            continue;
        
        if ($Require[$partName] && !$url[$partName])
            $errArr[$errCodeMissing[$partName]] = $errCodeMissing[$partName];
        
        if ($Forbid[$partName] && $url[$partName])
            $errArr[$errCodeMissing[$partName]] = $errCodeInvalid[$partName];
    }
    
    /* Construct an estimate of what the value should've been */
    if ($options['AssumeProtocol'] && !$url['Protocol'] && ($url['Server'] || (!$url['Server'] && !$url['Resource'])))
        $url['Protocol'] = $options['AssumeProtocol'];
    
    $value = $url['Protocol'];
    
    if ($url['Protocol'])
    {
        if ($url['Protocol'] == 'mailto' | $url['Protocol'] == 'mailto')
            $value.= ':';
        else
        $value.= '://';
    }
    
    if ($url['User'])
    {
        if ($url['Password'])
            $value.= "{$url['User']}:{$url['Password']}";
        else
        $value.= "{$url['User']}";
        
        if ($url['Server'])
            $value.= '@';
    }
    
    $value.= $url['Server'];
    
    if ($url['Port'])
        $value.= ":{$url['Port']}";
    
    if ($url['Server'] && $url['Resource'])
        $value.= "/";
    
    $value.= $url['Resource'];
    
    if ($url['QueryString'])
        $value.= "?{$url['QueryString']}";
    
    if ($url['Anchor'])
        $value.= "#{$url['Anchor']}";
    
    $r = array('Result' => count($errArr) ? $errArr : EW_OK, 'Value' => $value, 'URLParts' => $url);
    
    return $r;
    
}

?>
